package com.base.cn.platform.os.common.mybatis;

import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.entity.user.integral.CusUserIntegralRecord;
import com.base.cn.platform.os.entity.user.integral.IntegralRule;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
 * 业务基础类
 */
public abstract class BaseBiz<T extends IEntity,K extends BaseDao<T>> {
    public Logger logger = LoggerFactory.getLogger(this.getClass());

    protected K baseDao;
    private Class<T> entityClass;

    private Class<T> getEntityClass(){
        if(this.entityClass==null){
            Type type = getClass().getGenericSuperclass();
            Type trueType = ((ParameterizedType) type).getActualTypeArguments()[0];
            this.entityClass = (Class<T>) trueType;
        }
        return this.entityClass;
    }

    @Autowired
    public final void setBaseDao(K baseDao){
        this.baseDao = baseDao;
    }

    /**
     * 单条记录添加
     * @param entity 记录数据对象
     * @param tableName 表名
     */
    public void save(T entity,String tableName){
        if(entity.getCreateTime()==null){
            entity.setCreateTime(new Date());
        }
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.saveTableName(entity,tableName);
    }

    /**
     * 单条记录添加
     * @param entity 记录数据对象
     */
    public void save(T entity){
        if(entity.getCreateTime()==null){
            entity.setCreateTime(new Date());
        }
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.save(this.getEntityClass(),entity);
    }

    /**
     * 批量添加
     * @param list 数据列表
     * @param tableName 表名
     */
    public void batchSave(List<T> list,String tableName){
        if(list.size()<2){
            this.save(list.get(0),tableName);
        }else{
            list.forEach(e->{
                if(e==null){
                    list.remove(e);
                }
            });
            this.baseDao.batchSaveTableName(list,tableName);
        }
    }

    /**
     * 批量添加
     * @param list 数据列表
     */
    public void batchSave(List<T> list){
        if(list.size()<2){
            this.save(list.get(0));
        }else{
            list.forEach(e->{
                if(e==null){
                    list.remove(e);
                }
            });
            this.baseDao.batchSave(this.getEntityClass(),list);
        }
    }

    /**
     * 修改数据
     * @param entity 修改数据对象
     * @param idName 记录的ID列名
     * @param tableName 表名
     */
    public void updateById(T entity,String idName,String tableName){
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.updateByIdTableName(entity,idName,tableName);
    }

    /**
     * 修改数据
     * @param entity 修改数据对象
     * @param idName 记录的ID列名
     */
    public void updateById(T entity,String idName){
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.updateById(this.getEntityClass(),entity,idName);
    }

    /**
     * 条件修改
     * @param entity 修改数据对象
     * @param whereSql 修改条件
     * @param tableName 表名
     */
    public void updateByWhereSql(T entity,String whereSql,String tableName){
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.updateByTableNameWhereSql(entity,whereSql,tableName);
    }

    /**
     * 条件修改
     * @param entity 修改数据对象
     * @param whereSql 修改条件
     */
    public void updateByWhereSql(T entity,String whereSql){
        if(entity.getUpdateTime()==null){
            entity.setUpdateTime(new Date());
        }
        this.baseDao.updateByWhereSql(this.getEntityClass(),entity,whereSql);
    }

    /**
     * 批量更新
     * @param entityList 实体列表
     * @param tableName 表名
     */
    public void updateBatch(List<T> entityList,String tableName){
        if(ObjectUtils.isNotEmpty(entityList)){
            if(entityList.size()>1){
                this.baseDao.updateBatchTableName(entityList,tableName);
            }else{
                entityList.get(0).setUpdateTime(new Date());
                this.baseDao.updateByIdTableName(entityList.get(0),null,tableName);
            }
        }
    }

    /**
     * 批量更新
     * @param entityList 实体列表
     */
    public void updateBatch(List<T> entityList){
        if(ObjectUtils.isNotEmpty(entityList)){//MyCat有问题，批量更新时，只能一条的会报错，两条以上就没问题
            if(entityList.size()>1){
                this.baseDao.updateBatch(this.getEntityClass(),entityList);
            }else{
                entityList.get(0).setUpdateTime(new Date());
                this.baseDao.updateById(this.getEntityClass(),entityList.get(0),null);
            }
        }
    }

    /**
     * 通过ID删除
     * @param id ID
     */
    public void deleteById(BigDecimal id,String tableName){
        this.baseDao.deleteByIdTableName(this.getEntityClass(),id,tableName);
    }

    /**
     * 通过ID删除
     * @param id ID
     */
    public void deleteById(BigDecimal id){
        this.baseDao.deleteById(this.getEntityClass(),id);
    }

    /**
     * 批量删除
     * @param whereSql 删除条件
     * @param tableName 表名
     */
    public void deleteWhereSql(String whereSql,String tableName){
        this.baseDao.deleteWhereSqlTableName(this.getEntityClass(),whereSql,tableName);
    }

    /**
     * 批量删除
     * @param whereSql 删除条件
     */
    public void deleteWhereSql(String whereSql){
        this.baseDao.deleteWhereSql(this.getEntityClass(),whereSql);
    }


    /**
     * 通过ID查询数据
     * @param id  查询的ID
     * @return 数据对象
     */
    public T findByIdTable(BigDecimal id,String tableName){
        return this.baseDao.findByIdTableName(this.getEntityClass(),id,tableName);
    }

    /**
     * 通过ID查询数据
     * @param id  查询的ID
     * @return 数据对象
     */
    public T findById(BigDecimal id){
        return this.baseDao.findById(this.getEntityClass(),id);
    }

    /**
     * 通过ID查询数据
     * @param id  查询的ID
     * @param containColumns  只查询的列
     * @return 数据对象
     */
    public T findById(BigDecimal id,List<String> containColumns,String tableName){
        return this.baseDao.findByIdContainTableName(this.getEntityClass(),id,containColumns,tableName);
    }

    /**
     * 通过ID查询数据
     * @param id  查询的ID
     * @param containColumns  只查询的列
     * @return 数据对象
     */
    public T findById(BigDecimal id,List<String> containColumns){
        return this.baseDao.findByIdContain(this.getEntityClass(),id,containColumns);
    }

    /**
     * 条件查询，且最多返回一条数据
     * @param whereSql 查询条件
     * @param containColumns 要查询的列表，不填写查询所有的列
     * @param tableName 表名
     * @return 数据对象
     */
    public T findOne(String whereSql,List<String> containColumns,String tableName){
        List<T> list = this.baseDao.findTableName(this.getEntityClass(),whereSql,tableName,1,containColumns);
        if(!ObjectUtils.isEmpty(list)){
            return list.get(0);
        }
        return null;
    }

    /**
     * 条件查询，且最多返回一条数据
     * @param whereSql 查询条件
     * @param containColumns 要查询的列表，不填写查询所有的列
     * @return 数据对象
     */
    public T findOne(String whereSql,List<String> containColumns){
        List<T> list = this.baseDao.find(this.getEntityClass(),whereSql,1,containColumns);
        if(!ObjectUtils.isEmpty(list)){
            return list.get(0);
        }
        return null;
    }

    /**
     * 条件查询
     * @param whereSql 查询条件
     * @param count 查询量
     * @param containColumns 要查询的列表，不填写查询所有的列
     * @return 数据列表
     */
    public List<T> find(String whereSql,
                        Integer count,
                        List<String> containColumns,String tableName){
        return this.baseDao.findTableName(this.getEntityClass(),whereSql,tableName,count,containColumns);
    }

    /**
     * 条件查询
     * @param whereSql 查询条件
     * @param count 查询量
     * @param containColumns 要查询的列表，不填写查询所有的列
     * @return 数据列表
     */
    public List<T> find(String whereSql,
                        Integer count,
                        List<String> containColumns){
        return this.baseDao.find(this.getEntityClass(),whereSql,count,containColumns);
    }

    /**
     * 条件查询
     * @param whereSql 查询条件
     * @param page 分页条件对象
     * @param containColumns 要查询的列表，不填写查询所有的列
     * @return 数据列表
     */
    public PageInfo<T> findPage(String whereSql,
                                Pagination page,
                                List<String> containColumns){
        PageHelper.startPage(page.getCurrentPage(),page.getPageSize());
        Page<T> dataList = this.baseDao.findPage(this.getEntityClass(),whereSql,containColumns);
        PageInfo<T> pageInfo = new PageInfo<T>(dataList); //默认导航显示页数8
        //PageInfo<T> pageInfo = new PageInfo<T>(dataList,9);//设置导航显示页数为9
        return pageInfo;
    }

    /**
     * 查询表的总和
     * @param whereSql 查询条件
     * @return 记录数量
     */
    public BigDecimal count(String whereSql){
        return this.baseDao.count(this.getEntityClass(),whereSql);
    }

    /**
     * 查询表的总和
     * @param sumColumn 查询总量列
     * @param whereSql 查询条件
     * @return 记录数量
     */
    public BigDecimal sum(String sumColumn,String whereSql){
        return this.baseDao.sum(this.getEntityClass(),sumColumn,whereSql);
    }

}
